﻿using System;
using System.Threading;
using MangoCannon.Framework.Bussness;
using MangoCannon.Framework.Socket;

namespace MangoCannon.Framework.Base
{
    public class FrameworkService : IFramework
    {
        private ISocketService socketService;
        private IBaseApp[] apps;
        public FrameworkService(IBaseApp[] apps)
        {
            this.apps = apps;
            socketService = new SocketService();
            socketService.listenStarted += SocketService_listenStarted;
            socketService.listenStop += SocketService_listenStop;
            socketService.clientJoin += SocketService_clientJoin;
            socketService.clientRealJoin += SocketService_clientRealJoin;
            socketService.clientLeave += SocketService_clientLeave;
            socketService.clientMessage += SocketService_clientMessage;
        }

        public void startSocket()
        {
            socketService.start("upcs", 2333);
        }

        /// <summary>
        /// 客户加入时
        /// </summary>
        private void SocketService_clientJoin(object sender, EventArgs e)
        {
            Console.WriteLine("[" + ((ServiceEventArgs)e).clientAlias + "] client joined!");
        }

        /// <summary>
        /// 客户加入并发送首次心跳包
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SocketService_clientRealJoin(object sender, EventArgs e)
        {
            Console.WriteLine("[" + ((ServiceEventArgs)e).clientAlias + "] client real joined!");
            ClientHandle ch = ClientManager.getIns().getHandle(((ServiceEventArgs)e).clientAlias);
            //建立会话
            ClientSessionManager.getIns().newSession(ch);
            foreach (IBaseApp item in this.apps)
            {
                try
                {
                    item.join(ch, false);
                }
                catch (Exception)
                {
                    Console.WriteLine("Send message to apps fail!");
                }
            }
        }
        /// <summary>
        /// 客户发来了消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SocketService_clientMessage(object sender, EventArgs e)
        {
            ServiceMessageArgs ex = (ServiceMessageArgs)e;
            foreach (IBaseApp item in this.apps)
            {
                try
                {
                    item.message(Socket.ClientManager.getIns().getHandle(ex.clientAlias), new MessageReader().exchange(ex.message));
                }
                catch (Exception)
                {
                    Console.WriteLine("Send message to apps fail!");
                }
            }
        }

        /// <summary>
        /// 客户离开时
        /// </summary>
        private void SocketService_clientLeave(object sender, EventArgs e)
        {
            Console.WriteLine("[" + ((ServiceEventArgs)e).clientAlias + "] client leave!");
            ClientHandle ch = ClientManager.getIns().getHandle(((ServiceEventArgs)e).clientAlias);
            switch (((ServiceEventArgs)e).error)
            {
                case System.Net.Sockets.SocketError.ConnectionReset:
                    //ClientSessionManager.getIns().delSession(ch);
                    break;
                case System.Net.Sockets.SocketError.HostDown:
                    ClientSessionManager.getIns().delSession(ch);
                    break;
                default:
                    break;
            }
            foreach (IBaseApp item in this.apps)
            {
                try
                {
                    if (null != ch)
                    {
                        item.leave(ch, false);
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine("Send message to apps fail!");
                }
            }
            ClientManager.getIns().rmHandle(((ServiceEventArgs)e).clientAlias);
        }

        /// <summary>
        /// 监听停止时
        /// </summary>
        private void SocketService_listenStop(object sender, EventArgs e)
        {
            Console.WriteLine("[" + ((ServiceEventArgs)e).serverAlias + "] server listen stop!");
            foreach (IBaseApp item in this.apps)
            {
                try
                {
                    item.stopListen();
                }
                catch (Exception)
                {
                    Console.WriteLine("Send message to apps fail!");
                }
            }
        }

        /// <summary>
        /// 监听启动时
        /// </summary>
        private void SocketService_listenStarted(object sender, EventArgs e)
        {
            Console.WriteLine("[" + ((ServiceEventArgs)e).serverAlias + "] server listen start!");
            foreach (IBaseApp item in this.apps)
            {
                try
                {
                    item.startListen();
                }
                catch (Exception)
                {
                    Console.WriteLine("Send message to apps fail!");
                }
            }
        }

        public void luanch()
        {
            foreach (IBaseApp item in this.apps)
            {
                item.luanch();
            }
        }

        public void shutdown()
        {
            ClientSessionManager.getIns().clearAll();
            socketService.shutdown();
            foreach (IBaseApp item in this.apps)
            {
                item.shutdown(0);
            }
        }
    }
}
